package com.guyuan.live_meeting.service;

import com.google.gson.Gson;
import com.guyuan.live_meeting.ConstantValues;
import com.guyuan.live_meeting.bean.*;
import com.guyuan.live_meeting.entities.MeetingEntity;
import com.guyuan.live_meeting.repositories.MeetingRepo;
import com.guyuan.live_meeting.utils.TimeUtils;
import com.guyuan.live_meeting.utils.UmengHttpClient;
import com.guyuan.live_meeting.utils.UmengUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.logging.Logger;

import static com.guyuan.live_meeting.ConstantValues.CONST_ERROR_CODE_APPOINT_MEETING_TIME_ERROR;
import static com.guyuan.live_meeting.ConstantValues.CONST_ERROR_CODE_MEETING_NOT_EXIST;

@RestController
@RequestMapping("/meeting")
public class MeetingService {

    @Autowired
    private MeetingRepo meetingRepo;
    @Autowired
    private UmengHttpClient umengHttpClient;
    private Logger mLogger = Logger.getLogger(MeetingService.class.getName());

    @PostMapping("/startMeeting")
    public BaseNetResponse startMeeting(@RequestBody MeetingBean meeting) {
        mLogger.warning(meeting.toString());
        meeting.setMeetingType(MeetingBean.MEETING_TYPE_INSTANT);
        meeting.setScheduleTime(System.currentTimeMillis());
        return prepareMeeting(meeting, ConstantValues.CONST_MEETING_STATUS_CODE_ON_GOING);
    }

    private BaseNetResponse prepareMeeting(MeetingBean meeting, int status) {

        MeetingEntity meetingEntity = meeting.toMeetingEntity();
        meetingEntity.setStatusFlag(status);

        MeetingEntity entity = meetingRepo.save(meetingEntity);
        meeting.setMeetingId(entity.getMeetingId());

        StringBuilder receivers = new StringBuilder();
        Iterator<StaffBean> iterator = meeting.getReceivedUser().iterator();
        while (iterator.hasNext()) {
            StaffBean next = iterator.next();
            receivers.append(UmengUtils.genUserAlias(next.getName(), next.getId()));
            if (iterator.hasNext()) {
                receivers.append(",");
            }
        }

        BaseNetResponse netResponse = null;
        UmengPushResponse pushResponse = null;
        UmengHttpClient.ExtraDataType extraDataType = null;
        int meetingType = meeting.getMeetingType();
        switch (meetingType) {
            case MeetingBean.MEETING_TYPE_INSTANT:
                extraDataType = UmengHttpClient.ExtraDataType.INSTANT_MEETING;
                break;
            case MeetingBean.MEETING_TYPE_APPOINT_AUTO:
                extraDataType = UmengHttpClient.ExtraDataType.AUTO_APPOINT_MEETING;
                break;
            case MeetingBean.MEETING_TYPE_APPOINT_MANUAL:
                extraDataType = UmengHttpClient.ExtraDataType.MANUAL_APPOINT_MEETING;
                break;
            default:
                extraDataType = UmengHttpClient.ExtraDataType.DEFAULT;
                break;
        }
        //请求友盟推送
        try {
            pushResponse = umengHttpClient.umungPushPlusVendorPush(
                    receivers.toString(),
                    extraDataType,
                    new Gson().toJson(meeting),
                    meeting.getTitle(),
                    meeting.getTitle(),
                    meeting.getContent()
            );
        } catch (IOException e) {
            e.printStackTrace();
            netResponse = new ErrorNetResponse(404, e.getMessage());
        }

        //把推送结果返回
        if (pushResponse != null) {
            String ret = pushResponse.getRet();
            if (ret.equals("SUCCESS")) {
                netResponse = new OkNetResponse<Long>(entity.getMeetingId());
            } else {
                UmengPushResponse.Data data = pushResponse.getData();
                netResponse = new ErrorNetResponse(data.getError_code(), data.getError_msg());
            }
        } else {
            if (netResponse == null) {
                netResponse = new ErrorNetResponse(404, "友盟服务器生成推送失败");
            }
        }

        if (netResponse instanceof ErrorNetResponse) {
            //如果发送推送失败，清除此次会议。
            meetingRepo.delete(meetingEntity);
        }

        return netResponse;
    }

    @GetMapping(value = "/endMeeting", params = {"id"})
    public BaseNetResponse endMeeting(@RequestParam("id") long id) {
        Optional<MeetingEntity> optionalMeetingEntity = meetingRepo.findById(id);
        if (optionalMeetingEntity.isPresent()) {
            MeetingEntity entity = optionalMeetingEntity.get();
            entity.setStatusFlag(ConstantValues.CONST_MEETING_STATUS_CODE_ENDED);
            MeetingEntity save = meetingRepo.save(entity);
            int result = save.getStatusFlag() == entity.getStatusFlag() ? 1 : 0;
            if (result == 1) {
                try {
                    umengHttpClient.umengPushOnly(
                            entity.getReceivedUsers() + "," + entity.getSendUser(),
                            UmengHttpClient.ExtraDataType.MEETING_ENDED,
                            new Gson().toJson(MeetingBean.convertFromEntity(entity)),
                            "会议结束",
                            entity.getTitle(),
                            entity.getContent()
                    );
                } catch (Exception e) {
                    mLogger.warning(e.getMessage());
                }
            }
            return new OkNetResponse<>(result);
        }
        return new ErrorNetResponse(ConstantValues.CONST_ERROR_CODE_MEETING_NOT_EXIST, "会议不存在");
    }


    @GetMapping(value = "/checkMeetingStatus", params = {"meetingId"})
    public BaseNetResponse checkMeetingStatus(@RequestParam("meetingId") long meetingId) {
        Optional<MeetingEntity> meetingEntityOptional = meetingRepo.findById(meetingId);
        if (meetingEntityOptional.isPresent()) {
            MeetingEntity entity = meetingEntityOptional.get();
            return new OkNetResponse<>(entity.getStatusFlag());
        } else {
            return new ErrorNetResponse(ConstantValues.CONST_ERROR_CODE_MEETING_NOT_EXIST, "会议不存在");
        }
    }

    @PostMapping("/appointAutoMeeting")
    public BaseNetResponse appointAutoMeeting(@RequestBody MeetingBean meeting) {
        meeting.setMeetingType(MeetingBean.MEETING_TYPE_APPOINT_AUTO);
        long scheduleTime = meeting.getScheduleTime();
        if (System.currentTimeMillis() >= scheduleTime) {
            return new ErrorNetResponse(CONST_ERROR_CODE_APPOINT_MEETING_TIME_ERROR, "预约时间不能小于当前系统时间");
        }
        return prepareMeeting(meeting, ConstantValues.CONST_MEETING_STATUS_CODE_APPOINTED);
    }

    @PostMapping("/appointManualMeeting")
    public BaseNetResponse appointManualMeeting(@RequestBody MeetingBean meeting) {
        meeting.setMeetingType(MeetingBean.MEETING_TYPE_APPOINT_MANUAL);
        long scheduleTime = meeting.getScheduleTime();
        if (System.currentTimeMillis() >= scheduleTime) {
            return new ErrorNetResponse(CONST_ERROR_CODE_APPOINT_MEETING_TIME_ERROR, "预约时间不能小于当前系统时间");
        }
        return prepareMeeting(meeting, ConstantValues.CONST_MEETING_STATUS_CODE_APPOINTED);
    }

    @PostMapping("/editAppointment")
    public BaseNetResponse editMeetingAppointment(@RequestBody MeetingBean meeting) {
        long scheduleTime = meeting.getScheduleTime();
        if (System.currentTimeMillis() >= scheduleTime) {
            return new ErrorNetResponse(CONST_ERROR_CODE_APPOINT_MEETING_TIME_ERROR, "预约时间不能小于当前系统时间");
        }

        Optional<MeetingEntity> entityOptional = meetingRepo.findById(meeting.getMeetingId());
        if (entityOptional.isPresent()) {
            MeetingEntity meetingEntity = entityOptional.get();
            if (meetingEntity.getStatusFlag() == ConstantValues.CONST_MEETING_STATUS_CODE_APPOINTED) {
                MeetingEntity entity = meeting.toMeetingEntity();
                entity.setMeetingId(meeting.getMeetingId());
                entity.setStatusFlag(ConstantValues.CONST_MEETING_STATUS_CODE_APPOINTED);
                meetingRepo.save(entity);

                StringBuilder sb = new StringBuilder();
                List<StaffBean> receivers = meeting.getReceivedUser();
                Iterator<StaffBean> iterator = receivers.iterator();
                while (iterator.hasNext()) {
                    StaffBean next = iterator.next();
                    sb.append(UmengUtils.genUserAlias(next.getName(), next.getId()));
                    if (iterator.hasNext()) {
                        sb.append(",");
                    }
                }
                StringBuilder text = new StringBuilder();
                text.append(meeting.getSendUser().getName()).append("修改了会议预约，请查看会议列表。");
                try {
                    umengHttpClient.umengPushOnly(sb.toString(),
                            UmengHttpClient.ExtraDataType.MEETING_EDITED,
                            new Gson().toJson(meeting),
                            "会议预约更新",
                            "会议预约更新",
                            text.toString());
                } catch (IOException e) {
                    e.printStackTrace();
                }

                return new OkNetResponse<>(meeting.getMeetingId());
            } else {
                return new ErrorNetResponse(ConstantValues.CONST_ERROR_CODE_APPOINT_MEETING_STATUS_ERROR, "必须为未启动的预约会议。");
            }
        } else {
            return new ErrorNetResponse(CONST_ERROR_CODE_MEETING_NOT_EXIST, "无此会议记录。");
        }
    }

    @GetMapping(value = "/refuseMeeting", params = {"meetingId", "userId", "userName"})
    public BaseNetResponse refuseMeeting(@RequestParam("meetingId") long meetingId,
                                         @RequestParam("userId") long userId,
                                         @RequestParam("userName") String userName) {
        Optional<MeetingEntity> result = meetingRepo.findById(meetingId);
        if (result.isPresent()) {
            MeetingEntity entity = result.get();
            if (entity.getStatusFlag() != ConstantValues.CONST_MEETING_STATUS_CODE_ON_GOING) {
                return new ErrorNetResponse(ConstantValues.CONST_ERROR_CODE_MEETING_STATUS_ERROR, "会议未开始，不能拒绝会议");
            }
            String receivedUsers = entity.getReceivedUsers();
            receivedUsers = receivedUsers.replace(UmengUtils.genUserAlias(userName, userId), "").trim();
            receivedUsers = receivedUsers.replace(",,", ",").trim();
            receivedUsers = receivedUsers + "," + entity.getSendUser();
            StaffBean staffBean = new StaffBean();
            staffBean.setName(userName);
            staffBean.setId(userId);
            try {
                umengHttpClient.umengPushOnly(
                        receivedUsers,
                        UmengHttpClient.ExtraDataType.REFUSE_MEETING,
                        new Gson().toJson(staffBean),
                        "会议信息更新",
                        "缺席",
                        userName + "不能出席会议。");
            } catch (IOException e) {
                e.printStackTrace();
            }
            return new OkNetResponse<>(1);
        } else {
            return new ErrorNetResponse(CONST_ERROR_CODE_MEETING_NOT_EXIST, "无此会议记录");
        }
    }

    @GetMapping(value = "/getAttendMeetingList", params = {"userName", "userId"})
    public BaseNetResponse getAttendMeetingList(@RequestParam("userName") String userName,
                                                @RequestParam("userId") long userId) {
        List<MeetingBean> results = new ArrayList<>();
        Iterable<MeetingEntity> iterable = meetingRepo.findAll();
        String userAlias = UmengUtils.genUserAlias(userName, userId);
        for (MeetingEntity entity : iterable) {
            if (entity.getReceivedUsers().contains(userAlias) || entity.getSendUser().contains(userAlias)) {
                try {
                    results.add(MeetingBean.convertFromEntity(entity));
                } catch (Exception e) {
                    mLogger.warning(e.getMessage());
                }
            }
        }

        return new OkNetResponse<>(results);
    }

    @GetMapping(value = "/deleteMeeting",params = {"userName","userId","meetingId"})
    public BaseNetResponse deleteMeeting(@RequestParam("userName") String userName,
                                         @RequestParam("userId") long userId,
                                         @RequestParam("meetingId") long meetingId){
        Optional<MeetingEntity> repoById = meetingRepo.findById(meetingId);
        if(repoById.isPresent()){
            MeetingEntity entity = repoById.get();
            if(entity.getSendUser().equals(UmengUtils.genUserAlias(userName,userId))){
                meetingRepo.delete(entity);
                if(entity.getStatusFlag()==MeetingBean.STATUS_FLAG_APPOINTED){
                    try {
                        umengHttpClient.umungPushPlusVendorPush(
                                entity.getReceivedUsers(),
                                UmengHttpClient.ExtraDataType.MEETING_CANCEL,
                                new Gson().toJson(MeetingBean.convertFromEntity(entity)),
                                "会议取消",
                                "会议取消",
                                userName+"取消了原本将于"+ TimeUtils.toMonthDayHourMin(entity.getMeetingTime())+"的视频会议"
                        );
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                return new OkNetResponse<>("1");
            }else {
                return new ErrorNetResponse(ConstantValues.CONST_ERROR_CODE_USER_PERMISSION,"用户没有删除此会议的权限");
            }
        }else {
            return new ErrorNetResponse(CONST_ERROR_CODE_MEETING_NOT_EXIST,"会议不存在");
        }

    }


}
